package com.samehope.ar.service.impl;

import com.samehope.ar.constant.DelFlagEnum;
import com.samehope.ar.constant.IsTempEnum;
import com.samehope.ar.dto.RouteAndParam;
import com.samehope.ar.dto.RoutePointParam;
import com.samehope.ar.dto.RouteUpdateParam;
import com.samehope.ar.entity.PatrolRoute;
import com.samehope.ar.entity.PatrolRoutePoint;
import com.samehope.ar.mapper.PatrolRouteMapper;
import com.samehope.ar.service.IPatrolRoutePointService;
import com.samehope.ar.service.IPatrolRouteService;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.samehope.ar.util.SessionUtil;
import com.samehope.ar.util.TreeUtils;
import com.samehope.ar.vo.RouteDetailVO;
import com.samehope.ar.vo.TreeDataVO;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import java.time.LocalDateTime;
import java.util.ArrayList;
import java.util.List;

/**
 * <p>
 * 巡检路线 服务实现类
 * </p>
 *
 * @author Zhang Luo
 * @since 2019-12-23
 */
@Service
public class PatrolRouteServiceImpl extends ServiceImpl<PatrolRouteMapper, PatrolRoute> implements IPatrolRouteService {

    @Autowired
    private IPatrolRoutePointService routePointService;

    /**
     * 查询线路树结构
     * @param condition
     * @return
     */
    @Override
    public List<TreeDataVO> getRouteTree(String condition) {
        List<TreeDataVO> tree = this.baseMapper.getRouteTreeByProjectAndCondition(SessionUtil.getProjectId(), condition);
        TreeUtils.setLevel(tree, 1);
        TreeUtils.setId(tree);
        return tree;
    }

    /**
     * 删除线路
     * @param routeId
     */
    @Override
    public void deleteRoute(Long routeId) {

        PatrolRoute patrolRoute = this.baseMapper.findByProjectAndRoute(SessionUtil.getProjectId(), routeId);

        if (patrolRoute == null) {
            throw new IllegalArgumentException("线路不存在");
        }

        patrolRoute.setDelFlag(DelFlagEnum.DELETED.getCode());
        patrolRoute.setUpdateBy(SessionUtil.getUserId());
        patrolRoute.setUpdateDate(LocalDateTime.now());

        this.updateById(patrolRoute);
    }

    /**
     * 添加线路
     * @param param
     */
    @Transactional(rollbackFor = Exception.class)
    @Override
    public Long add(RouteAndParam param) {

        final LocalDateTime now = LocalDateTime.now();

        PatrolRoute patrolRoute = this.baseMapper.findByProjectAndName(SessionUtil.getProjectId(), param.getRouteName());

        if (patrolRoute != null) {
            throw new IllegalArgumentException("线路名称已存在");
        }

        patrolRoute = new PatrolRoute();
        patrolRoute.setCompanyId(SessionUtil.getCompanyId());
        patrolRoute.setProjectId(SessionUtil.getProjectId());
        patrolRoute.setRouteName(param.getRouteName());
        if(param.getIsTemp() == null){
            patrolRoute.setIsTemp(IsTempEnum.NOMAL.getCode());
        }else{
            patrolRoute.setIsTemp(param.getIsTemp());
        }
        patrolRoute.setCreateBy(SessionUtil.getUserId());
        patrolRoute.setCreateDate(now);

        this.save(patrolRoute);

        List<PatrolRoutePoint> routePoints = new ArrayList<>();
        for (int i = 0; i < param.getPoints().size(); i++) {

            RoutePointParam routePointParam = param.getPoints().get(i);

            PatrolRoutePoint routePoint = new PatrolRoutePoint();
            routePoint.setProjectId(SessionUtil.getProjectId());
            routePoint.setRouteId(patrolRoute.getId());
            routePoint.setPointId(routePointParam.getPointId());
            routePoint.setSortNo(routePointParam.getSortNo());
            routePoint.setCreateBy(SessionUtil.getUserId());
            routePoint.setCreateDate(now);

            routePoints.add(routePoint);
        }

        routePointService.saveBatch(routePoints);

        return patrolRoute.getId();
    }

    /**
     * 更新线路
     * @param param
     */
    @Transactional(rollbackFor = Exception.class)
    @Override
    public void update(RouteUpdateParam param) {

        final LocalDateTime now = LocalDateTime.now();

        PatrolRoute src = this.baseMapper.findByProjectAndRoute(SessionUtil.getProjectId(), param.getRouteId());

        if (src == null) {
            throw new IllegalArgumentException("线路不存在");
        }

        PatrolRoute patrolRoute = this.baseMapper.findByProjectAndName(SessionUtil.getProjectId(), param.getRouteName());

        if (patrolRoute != null && !src.getId().equals(patrolRoute.getId())) {
            throw new IllegalArgumentException("线路名称已存在");
        }

        if (!src.getRouteName().equals(param.getRouteName())) {
            src.setRouteName(param.getRouteName());
            src.setUpdateBy(SessionUtil.getUserId());
            src.setUpdateDate(now);
            this.updateById(src);
        }

        // 删除线路点关系
        List<PatrolRoutePoint> routePoints = routePointService.findByRoute(param.getRouteId());
        routePoints.forEach(e -> {
            e.setDelFlag(DelFlagEnum.DELETED.getCode());
            e.setUpdateBy(SessionUtil.getUserId());
            e.setUpdateDate(now);
        });
        routePointService.updateBatchById(routePoints);

        // 保存新的线路点关系
        routePoints = new ArrayList<>();
        for (int i = 0; i < param.getPoints().size(); i++) {

            RoutePointParam routePointParam = param.getPoints().get(i);

            PatrolRoutePoint routePoint = new PatrolRoutePoint();
            routePoint.setProjectId(SessionUtil.getProjectId());
            routePoint.setRouteId(patrolRoute.getId());
            routePoint.setPointId(routePointParam.getPointId());
            routePoint.setSortNo(routePointParam.getSortNo());
            routePoint.setCreateBy(SessionUtil.getUserId());
            routePoint.setCreateDate(now);

            routePoints.add(routePoint);
        }

        routePointService.saveBatch(routePoints);
    }

    /**
     * 线路详情
     * @param routeId
     * @return
     */
    @Override
    public RouteDetailVO detail(Long routeId) {
        return this.baseMapper.detailByProjectAndRoute(SessionUtil.getProjectId(), routeId);
    }

}
